Skip to main content

RSMS VM — worker as a Windows service (NSSM)

Environment: Production RSMS VM (Windows Server). The simulation worker runs as a Windows service wrapped by NSSM (Non-Sucking Service Manager), not Azure Functions.

Related: rsms-worker-implementation-plan (queue worker design), rsms-worker-ohio-riverflows-tls (Python TLS / certifi on this host).


Overview

The worker entrypoint is queue_worker.py: it polls Azure Storage Queue and runs the RSMS pipeline for each message. On RSMS VM we keep that process running under NSSM so it survives logoff, restarts on failure, and can start at boot.

Why NSSM

  • Straightforward wrapper for a long-running console process (here: python.exe + script).
  • Optional automatic restart if the process exits.
  • Configure via CLI or GUI; no custom C# Windows service project.
  • Works well with a per-VM Python virtual environment (explicit path to Scripts\python.exe).

Example paths (RSMS VM)

Adjust user name, drive, and clone location if your VM differs.

RoleExample path
Python (venv)C:\Users\gqc\Envs\rsms\Scripts\python.exe
Worker repo rootC:\RSMS\rsms-worker-function
Worker scriptC:\RSMS\rsms-worker-function\queue_worker.py
Working directoryC:\RSMS\rsms-worker-function (so imports, .env, and relative paths match manual runs)
LogsC:\RSMS\logs\ (create the folder before pointing NSSM at it)

Ensure local.settings.json, .env, or system/user environment variables supply AZURE_STORAGE_CONNECTION_STRING, RSMS_WORKER_QUEUE_NAME, EXE_DIR, and the rest per rsms-worker-function/README.md.


Install and configure NSSM (CLI)

  1. Install NSSM and ensure nssm.exe is on PATH (or invoke it with a full path).

  2. Create the service (opens a GUI on some versions; the set commands below apply either way):

    nssm install RSMSWorker
  3. Point the service at the venv Python and the queue worker:

    nssm set RSMSWorker Application "C:\Users\gqc\Envs\rsms\Scripts\python.exe"
    nssm set RSMSWorker AppParameters "queue_worker.py"
    nssm set RSMSWorker AppDirectory "C:\RSMS\rsms-worker-function"
  4. Logging (stdout/stderr files):

    nssm set RSMSWorker AppStdout "C:\RSMS\logs\worker-out.log"
    nssm set RSMSWorker AppStderr "C:\RSMS\logs\worker-err.log"

    Optional size-based rotation (NSSM only; not a substitute for structured app logging):

    nssm set RSMSWorker AppRotateFiles 1
    nssm set RSMSWorker AppRotateOnline 1
    nssm set RSMSWorker AppRotateBytes 10485760

    Prefer LOG_LEVEL and Python logging configuration for retention and fields you care about in production.

  5. Start the service:

    nssm start RSMSWorker

Use nssm edit RSMSWorker for a GUI review of all options (restart delay, exit action, etc.).


Start automatically at boot

PowerShell:

Set-Service -Name RSMSWorker -StartupType Automatic

Alternative (sc.exe, not the sc alias):

sc.exe config RSMSWorker start= auto

The space after start= is required.


Verification

Service configuration:

sc.exe qc RSMSWorker

Expect START_TYPE AUTO_START (value 2) when configured for automatic start.

Runtime:

  • Tail C:\RSMS\logs\worker-out.log and worker-err.log.
  • Confirm messages are consumed from the configured queue after the API returns 202 for a run.

Summary

CapabilityNSSM + queue_worker.py
Always-on workerYes — service runs until stopped
Restart on crashConfigure in NSSM (e.g. restart application on exit)
Boot persistenceAutomatic startup type
LogsNSSM stdout/stderr files; add app-level logging as needed

Typical next improvements: structured logging with rotation, monitoring/alerting on queue depth and process health, and (if needed) multiple worker instances or VMs for throughput.